import type { IQueue, IStructureObj } from "../types";

export default class Queue<T> implements IQueue<T> {
  private count: number;
  private items: IStructureObj<T>;
  private lowestCount: number;

  constructor() {
    this.count = 0;
    this.items = {};
    this.lowestCount = 0;
  }

  enqueue(item: T): void {
    this.items[this.count] = item;
    this.count++;
  }

  dequeue(): T | undefined {
    if (this.isEmpty()) return void 0;
    const result = this.items[this.lowestCount];
    delete this.items[this.lowestCount];
    this.lowestCount++;
    return result;
  }
  front(): T | undefined {
    if (this.isEmpty()) return void 0;
    return this.items[this.lowestCount];
  }
  isEmpty(): boolean {
    return this.size() === 0;
  }
  size(): number {
    return this.count - this.lowestCount;
  }
  clear(): void {
    this.count = 0;
    this.items = {};
    this.lowestCount = 0;
  }
  toString(): string {
    if (this.isEmpty()) return "";
    let result = `${this.items[this.lowestCount]}`;
    for (let i = this.lowestCount + 1; i < this.count; i++) {
      result = `${result},${this.items[i]}`;
    }
    return result;
  }
}
